# Test the chess moves

require 'chess-data'
require 'minitest/autorun'

describe ChessData::Moves do
  it "correctly packages move into type" do
    [["O-O", ChessData::Moves::KingsideCastles],
      ["O-O-O", ChessData::Moves::QueensideCastles],
      ["e4", ChessData::Moves::SimplePawnMove],
      ["e8=Q", ChessData::Moves::PromotionPawnMove],
      ["Qe8", ChessData::Moves::PieceMove],
      ["Bxf7+", ChessData::Moves::PieceMove],
      ["exd5", ChessData::Moves::PawnCapture],
      ["exd8=B", ChessData::Moves::PromotionPawnCapture]
    ].each do |defn|
      _(ChessData::Moves.new_move(defn[0])).must_be_kind_of defn[1]
    end
  end

  it "notices invalid move definitions" do
    assert_raises(ChessData::InvalidMoveError) { ChessData::Moves.new_move("rnd") }
  end

  it "check if pieces can reach squares correctly" do
    [ # rook moves
      ["R", "e4", "e8", true, "8/8/8/8/4R3/8/8/8"],
      ["R", "e4", "d8", false, "8/8/8/8/4R3/8/8/8"],
      ["r", "e4", "c4", true, "8/8/8/8/4r3/8/8/8"],
      # bishop moves
      ["B", "d4", "h8", true, "8/8/8/8/3R4/8/8/8"],
      ["b", "g8", "a2", true, "6b1/8/8/8/8/8/8/8"],
      ["B", "d4", "d8", false, "8/8/8/8/3B4/8/8/8"],
      ["b", "b4", "e1", false, "8/8/8/8/1b6/2N5/8/4K3"],
      # queen moves
      ["Q", "e4", "e8", true, "8/8/8/8/4Q3/8/8/8"],
      ["Q", "e4", "d8", false, "8/8/8/8/4Q3/8/8/8"],
      ["Q", "e4", "h1", true, "8/8/8/8/4Q3/8/8/8"],
      ["Q", "e4", "a1", false, "8/8/8/8/4Q3/8/8/8"],
      # king moves
      ["K", "e1", "f1", true, "8/8/8/8/8/8/8/4K3"],
      ["K", "e1", "f2", true, "8/8/8/8/8/8/8/4K3"],
      ["K", "e1", "f3", false, "8/8/8/8/8/8/8/4K3"],
      ["K", "e1", "g1", false, "8/8/8/8/8/8/8/4K3"],
      ["K", "e4", "d3", true, "8/8/8/8/4R3/8/8/8"],
      # knight moves
      ["N", "g1", "f3", true, "8/8/8/8/8/8/8/6N1"],
      ["N", "g1", "g3", false, "8/8/8/8/8/8/8/6N1"],
      ["n", "e5", "d7", true, "8/8/8/4n3/8/8/8/8"]
    ].each do |defn|
      if defn[3]
        assert ChessData::Moves.send(:can_reach, ChessData::Board.from_fen(defn[4]), defn[0], defn[1], defn[2]), 
          "test can reach #{defn.join(",")}"
      else
        assert !ChessData::Moves.send(:can_reach, ChessData::Board.from_fen(defn[4]), defn[0], defn[1], defn[2]),
          "test cannot reach #{defn.join(",")}"
      end
    end
  end
end
